package fnsvr

import "sync"

// nameRWMutex 是一个基于名称的读写锁管理器
type NamedRWMutex struct {
	mu    sync.Mutex
	locks map[string]*rwLockWithCount
}

// rwLockWithCount 是一个具有引用计数的读写锁
type rwLockWithCount struct {
	rw       sync.RWMutex
	refCount int
}

// NewNameRWMutex 创建一个新的 nameRWMutex
func NewNamedRWMutex() *NamedRWMutex {
	return &NamedRWMutex{
		locks: make(map[string]*rwLockWithCount),
	}
}

// Lock 根据名称获取锁并锁定
func (n *NamedRWMutex) Lock(name string) {
	n.mu.Lock()
	if _, exists := n.locks[name]; !exists {
		n.locks[name] = &rwLockWithCount{
			refCount: 0,
		}
	}
	lock := n.locks[name]
	lock.refCount++
	n.mu.Unlock()

	lock.rw.Lock()
}

// Unlock 根据名称解锁
func (n *NamedRWMutex) Unlock(name string) {
	n.mu.Lock()
	if lock, exists := n.locks[name]; exists {
		lock.refCount--
		lock.rw.Unlock()
		if lock.refCount <= 0 {
			delete(n.locks, name)
		}
	}
	n.mu.Unlock()
}

// RLock 根据名称获取锁并读锁定
func (n *NamedRWMutex) RLock(name string) {
	n.mu.Lock()
	if _, exists := n.locks[name]; !exists {
		n.locks[name] = &rwLockWithCount{
			refCount: 0,
		}
	}
	lock := n.locks[name]
	lock.refCount++
	n.mu.Unlock()

	lock.rw.RLock()
}

// RUnlock 根据名称解除读锁
func (n *NamedRWMutex) RUnlock(name string) {
	n.mu.Lock()
	if lock, exists := n.locks[name]; exists {
		lock.refCount--
		lock.rw.RUnlock()
		if lock.refCount <= 0 {
			delete(n.locks, name)
		}
	}
	n.mu.Unlock()
}
